/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package cap.jeeves.socialnetstar.backend

import cap.scalasmt._
import cap.jeeves._
import cap.jeeves.socialnetstar.backend._
import cap.jeeves.socialnetstar.backend.SocialNetStarBackend._
//import cap.jeeves.socialnetstar.backend.SocialNetStarUserRecord._
import org.scalatest.FunSuite
import org.scalatest.Assertions.{ expectResult }
import scala.collection.immutable.Map

class TestSocialNetStarBackend extends FunSuite {
  val MIT = SocialCircle("MIT");
  val jean = new SocialNetStarUserRecord(
    Name("Jean Yang"), OnlySelf,
    Email("jean@mit.edu"), OnlyFriends,
    MIT, OnlyFriends,
    OnlyFriends
  ,OnlyFriends  
  )
  val kuat = new SocialNetStarUserRecord(
    Name("Kuat Yessenov"), OnlyFriends,
    Email("kuat@mit.edu"), OnlySelf,
    MIT, OnlySelf,
    OnlyFriends
    ,OnlyFriends  
  )
  val joe = new SocialNetStarUserRecord(
    Name("Joe Near"), OnlySelf,
    Email("jnear@mit.edu"), OnlySelf,
    MIT, OnlyFriends,
    OnlySelf
    ,OnlySelf)

  addUser(jean);
  addUser(kuat);
  addUser(joe);
  addFriendship(kuat, jean);
  addFriendship(kuat, joe);

  test("name") {
    expectResult(null) { concretize(kuat, joe.name) }
    expectResult(null) { concretize(joe, jean.name) }
    expectResult(Name("Kuat Yessenov")) { concretize(jean, kuat.name) }
  }

  test("getFriends") {
    expectResult(kuat :: Nil) { concretize(kuat, jean.getFriends()) }
    expectResult(Nil) { concretize(joe, jean.getFriends()) }
    expectResult(Nil) { concretize(kuat, joe.getFriends()) }
  }

  test("isFriends") {
    expectResult(true) { concretize(jean, jean.isFriends(kuat)) }
    expectResult(true) { concretize(kuat, jean.isFriends(kuat)) }
    expectResult(true) { concretize(joe, joe.isFriends(kuat)) }
    expectResult(true) { concretize(jean, kuat.isFriends(joe)) }
    expectResult(false) { concretize(jean, joe.isFriends(kuat)) }
  }

  test("SocialCircles") {
    expectResult(MIT) { concretize(kuat, jean.circle) }
    expectResult(null) { concretize(jean, kuat.circle) }
    expectResult(jean :: Nil) { concretize(jean, getUsersBySocialCircle(MIT)) }
  }

  test("user posts") {

    // sample wall entries
    val entry_onlyself = new Entry("only I can see this", OnlySelf)
    val entry_onlyfriends = new Entry("only my friends can see this", OnlyFriends)
    val entry_anyone = new Entry("anyone can see this", Anyone)
    
    // initially, the wall is empty
    expectResult(Nil) { concretize(kuat, jean.getWall()) }

    jean.addEntry(entry_onlyself)
    expectResult(Nil) { concretize(kuat, jean.getWall()) }
    expectResult(Nil) { concretize(joe, jean.getWall()) }
    jean.addEntry(entry_onlyfriends)
    expectResult(Nil) { concretize(joe, jean.getWall()) }
    expectResult(entry_onlyfriends :: Nil) { concretize(kuat, jean.getWall()) }

    jean.addEntry(entry_anyone)
    expectResult(entry_onlyfriends:: entry_anyone :: Nil) { concretize(kuat, jean.getWall()) }
    expectResult(entry_anyone :: Nil) { concretize(joe, jean.getWall()) }
  }
  
  test ("post sharing") {
    val entry_helloworld = new Entry("Hello, world!",Anyone)
    
    expectResult(Nil) {concretize(kuat,kuat.getWall())}
    jean.shareEntryWith(entry_helloworld,kuat)
    expectResult(List(entry_helloworld)){concretize(kuat,kuat.getWall())}
  }

  test("email") {
    expectResult(null) { concretize(kuat, joe.email) }
    expectResult(null) { concretize(joe, jean.email) }
    expectResult(Email("kuat@mit.edu")) { concretize(kuat, kuat.email) }
  }

  test("state change") {
    val eunsuk = new SocialNetStarUserRecord(
      Name("Eunsuk Kang"), Anyone,
      Email("eskang@mit.edu"), Anyone,
      MIT, Anyone,
      Anyone
      ,Anyone);
    expectResult(null) { concretize(eunsuk, joe.circle) }
    addFriendship(joe, eunsuk)
    expectResult(MIT) { concretize(eunsuk, joe.circle) }
    removeFriendship(joe, eunsuk)
    expectResult(null) { concretize(eunsuk, joe.circle) }
  }

  test("geo location") {
    jean.setLocation(8, 8) // top
    kuat.setLocation(4, 4)
    joe.setLocation(0, 0) // bottom
    expectResult((1000, 1000)) { concretize(jean, joe.location) }
    expectResult((1000, 1000)) { concretize(joe, jean.location) }
    expectResult((0, 0)) { concretize(kuat, joe.location) }
    expectResult((8, 8)) { concretize(kuat, jean.location) }
    expectResult((4, 4)) { concretize(joe, kuat.location) }
    expectResult((4, 4)) { concretize(jean, kuat.location) }
    expectResult((4, 4)) { concretize(kuat, kuat.location) }
  }

  test("symbolic context") {
    expectResult(Set(Receipt(Email("kuat@mit.edu"), null))) {
      announceName(jean)
    }

    expectResult(Set(Receipt(null, null))) {
      announceName(joe)
    }
  }
}

